//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <ddk.h>
#include "testingserver.h"

#ifdef _win32

EXTERN_C ECode CaptureFrame(WChar *pwszPath);
EXTERN_C Int32 _waccess(const WChar* pwszPath, Int32 nMode);

#endif

class CTestingServer : public CDeviceDriver
{
public:
    CARAPI Read(
        /* [in] */ Int64 nOffset,
        /* [in] */ Int32 nNumberOfBytesToRead,
        /* [out] */ MemoryBuf * pData,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 nOffset,
        /* [in] */ const MemoryBuf & mbInData,
        /* [out] */ Int32 * pNumberOfBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf & mbInData,
        /* [out] */ MemoryBuf * pOutData,
        /* [out] */ IEvent * * ppCompletionEvent);

    virtual Void Dispose();

public:
    ECode Initialize();

public:

#ifndef _win32
    DzTimer *m_pTimer;
#endif
};

ECode CTestingServer::Read(
    /* [in] */ Int64 nOffset,
    /* [in] */ Int32 nNumberOfBytesToRead,
    /* [out] */ MemoryBuf * pData,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode CTestingServer::Write(
    /* [in] */ Int64 nOffset,
    /* [in] */ const MemoryBuf & mbInData,
    /* [out] */ Int32 * pNumberOfBytesWritten,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode CTestingServer::Control(
    /* [in] */ Handle32 nControlCode,
    /* [in] */ const MemoryBuf & mbInData,
    /* [out] */ MemoryBuf * pOutData,
    /* [out] */ IEvent * * ppCompletionEvent)
{
	ECode ec = NOERROR;

#ifndef _win32

    UInt32 uTime = 0, uTicks = 0;

    switch (nControlCode) {
        case TSCommand_StartRebootCountDown:
            uTime = *(UInt32 *)mbInData.GetPayload();
            uTicks = DzMillisecondsToTicks(uTime);

            m_pTimer->Restart(uTicks);
        break;

        case TSCommand_CancelRebootCountDown:
            m_pTimer->Cancel();
        break;

        case TSCommand_ResetbOutOfMemoryFalse:
        break;

        default:
        	ec = E_INVALID_ARGUMENT;
        break;
    }

	return ec;

#else

	WChar *pwszPath = NULL;

    switch (nControlCode) {
        case TSCommand_CaptureFrame :

        	pwszPath = (WChar *)mbInData.GetPayload();
        	if (!pwszPath) return E_INVALID_ARGUMENT;

			ec = CaptureFrame(pwszPath);
			if (FAILED(ec)) break;
        break;

        default:
            ec = E_INVALID_ARGUMENT;
        break;
    }

    return ec;

#endif
}

Void CTestingServer::Dispose()
{
    delete this;
}

#ifndef _win32
Void CDECL TimerRoutine(Void * pvParameter)
{
    kprintf("Testing-System: Timer control Rebooting...\n");
    BspReboot();
}

ECode CTestingServer::Initialize()
{
    UInt32 uTicks = DzMillisecondsToTicks(1000 * 1000);
    m_pTimer = new DzTimer(uTicks, TimerRoutine, NULL);
    if (!m_pTimer) return E_OUT_OF_MEMORY;

    m_pTimer->Start();
    m_pTimer->Cancel();

    return NOERROR;
}
#endif

EXTERN IDeviceDriver * CDECL CreateTestingServer(UInt32 uDeviceNo, Void *pvParameter)
{
    CTestingServer *pTestingServer = new CTestingServer;
    if (!pTestingServer) return NULL;

#ifndef _win32
    ECode ec = pTestingServer->Initialize();
    if (FAILED(ec)) {
        delete pTestingServer;
        return NULL;
    }
#endif

	pTestingServer->AddRef();

    return pTestingServer;
}
